/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       convert_16_bit.cpp

	$Header: /game/convert_16_bit.cpp $

	$NoKeywords: $

 ************************************************************************/

#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "convert_16_bit.h"

#include "vector_set.h"

// -------------------------------------------------------------------------
// Unnamed namespace
// -------------------------------------------------------------------------

namespace
{
	// -------------------------------------------------------------------------
	// -------------------------------------------------------------------------
	typedef t_vector_set< t_pixel_mask_viewer * > t_pixel_mask_viewer_ptr_set;
	inline t_pixel_mask_viewer_ptr_set & get_pixel_mask_viewer_ptrs()
	{
		static t_pixel_mask_viewer_ptr_set instance;
		return instance;
	}

} // Unnamed namespace

int g_blue_16_bit_mask;
int g_blue_16_bit_mask_shifted;
int g_blue_16_bit_shift;
int g_green_16_bit_mask;
int g_green_16_bit_shift;
int g_green_16_bit_mask_shifted;
int g_red_16_bit_mask;
int g_red_16_bit_shift;
int g_red_16_bit_mask_shifted;
int g_alpha_16th_mask;
int g_alpha_8th_mask;
int g_alpha_4th_mask;
int g_alpha_half_mask;

int g_red_blue_16_bit_mask;
int g_red_blue_16_bit_mask_shifted;

int g_inverse_green_16_bit_mask;
int g_inverse_green_16_bit_mask_shifted;
int g_num_red_green_forward_shift;
int g_num_reg_green_backward_shift;
int g_green_red_blue_16_bit_mask;
int g_green_red_blue_16_bit_mask_shifted;

// -------------------------------------------------------------------------
// initialize the masks & shifts for 16 bit conversions
// -------------------------------------------------------------------------
void set_pixel_masks( t_uint16 red_mask, t_uint16 green_mask, t_uint16 blue_mask )
{
	bool     red_set	= false;
	bool     green_set	= false;
	bool     blue_set	= false;
	t_uint16 bit		= 0x8000;
	int      shift;

	g_blue_16_bit_mask = blue_mask;
	g_blue_16_bit_mask_shifted = g_blue_16_bit_mask << 4;
	g_green_16_bit_mask = green_mask;
	g_green_16_bit_mask_shifted = g_green_16_bit_mask << 4;
	g_red_16_bit_mask = red_mask;
	g_red_16_bit_mask_shifted = g_red_16_bit_mask << 4;

	g_alpha_half_mask = (((red_mask   >> 1) & red_mask  )
		               + ((green_mask >> 1) & green_mask)
					   + ((blue_mask  >> 1) & blue_mask )) << 1;
	g_alpha_4th_mask =  ((g_alpha_half_mask >> 1) & g_alpha_half_mask) << 1;
	g_alpha_8th_mask =  ((g_alpha_4th_mask >> 2 ) & g_alpha_half_mask) << 2;
	g_alpha_16th_mask = ((g_alpha_8th_mask >> 3 ) & g_alpha_half_mask) << 3;

	for (shift = 15; shift >= 0; shift--)
	{
		if (!red_set && (bit & red_mask) != 0)
		{
			red_set = true;
			g_red_16_bit_shift = shift - 7;
		}
		if (!green_set && (bit & green_mask) != 0)
		{
			green_set = true;
			g_green_16_bit_shift = shift - 7;
		}
		if (!blue_set && (bit & blue_mask) != 0)
		{
			blue_set = true;
			g_blue_16_bit_shift = 7 - shift;
		}
		bit >>= 1;
	}

	static t_pixel_mask_viewer_ptr_set & pixel_mask_viewer_ptrs = get_pixel_mask_viewer_ptrs();
	t_pixel_mask_viewer_ptr_set::const_iterator pixel_mask_viewer_ptr_iter = pixel_mask_viewer_ptrs.begin();
	for ( ; pixel_mask_viewer_ptr_iter != pixel_mask_viewer_ptrs.end(); ++pixel_mask_viewer_ptr_iter )
		( *pixel_mask_viewer_ptr_iter )->on_pixel_masks_changed();
	
	
	g_red_blue_16_bit_mask			= g_blue_16_bit_mask | g_red_16_bit_mask;
	g_red_blue_16_bit_mask_shifted	= g_blue_16_bit_mask_shifted | g_red_16_bit_mask_shifted;
	

	int g_inverse_green_16_bit_mask_shifted;
	int g_num_red_green_forward_shift;
	int g_num_reg_green_backward_shift;

	g_inverse_green_16_bit_mask			 = ~g_green_16_bit_mask;
	g_inverse_green_16_bit_mask_shifted	 = g_inverse_green_16_bit_mask<<4;
	g_num_red_green_forward_shift		 = 2*count_mask_bits16(red_mask) + count_mask_bits16(green_mask);
	g_num_reg_green_backward_shift		 = g_num_red_green_forward_shift -  count_mask_bits16(green_mask);
	g_green_red_blue_16_bit_mask		 = (g_green_16_bit_mask << g_num_red_green_forward_shift) | g_red_blue_16_bit_mask;
	g_green_red_blue_16_bit_mask_shifted = g_green_red_blue_16_bit_mask<<4;; 
}

// -------------------------------------------------------------------------
// t_pixel_mask_viewer members
// -------------------------------------------------------------------------

// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
t_pixel_mask_viewer::t_pixel_mask_viewer()
{
	get_pixel_mask_viewer_ptrs().insert( this );
}

// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
t_pixel_mask_viewer::~t_pixel_mask_viewer()
{
	get_pixel_mask_viewer_ptrs().erase( this );
}
